﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hotnet.Dal.NSDalNews;
using Hotnet.Entity;
using Ninject.Core;
using Hotnet.Biz.NSBizCommon;
using Hotnet.Entity.Enum;
using Hotnet.Entity.Search;

namespace Hotnet.Biz.NSBizNews
{
	public class BizNews : BaseBiz<News>
	{
		private static DalNews db = new DalNews();
		private BizNewsContent _BizNewsContent;
		private BizNewsContent BizNewsContent
		{
			get
			{
				if (_BizNewsContent == null)
					_BizNewsContent = new BizNewsContent();
				return _BizNewsContent;
			}
		}
		private BizNewsCategory _BizNewsCategory;
		private BizNewsCategory BizNewsCategory
		{
			get
			{
				if (_BizNewsCategory == null)
					_BizNewsCategory = new BizNewsCategory();
				return _BizNewsCategory;
			}
		}
		private BizSourceFrom _BizSourceFrom;
		private BizSourceFrom BizSourceFrom
		{
			get
			{
				if (_BizSourceFrom == null)
					_BizSourceFrom = new BizSourceFrom();
				return _BizSourceFrom;
			}
		}
		private BizNewsXTag _BizNewsXTag;
		private BizNewsXTag BizNewsXTag
		{
			get
			{
				if (_BizNewsXTag == null)
					_BizNewsXTag = new BizNewsXTag();
				return _BizNewsXTag;
			}
		}

		public BizNews() : base(db) { }

		public void DeleteAllByCategoryId(int categoryId)
		{
			var newses = db.ListBy(news => news.CategoryID == categoryId);
			foreach (var news in newses)
			{
				BizNewsXTag.DeleteAllByNewsId(news.NewsID);
				BizNewsContent.Delete(news.NewsID);
			}
			db.DeleteBy(news => news.CategoryID == categoryId);
		}

		public override void Delete(int newsID)
		{
			BizNewsXTag.DeleteAllByNewsId(newsID);
			BizNewsContent.Delete(newsID);
			db.Delete(newsID);
		}

		public News[] ListByCategoryId(int id, int pageSize, int pageNo, out int totalCount, bool isIncludeContent)
		{
			var newses = db.ListByCategoryId(id, pageSize, pageNo, out totalCount);

			foreach (var news in newses)
			{
				news.SourceFrom = BizSourceFrom.Get(news.SourceFromID);
				//news.NewsCategory = BizNewsCategory.Get(news.CategoryID);
				if (isIncludeContent)
				{
					news.NewsContent.AddRange(BizNewsContent.ListNewsContentByNewsID(news.NewsID));
				}
			}
			return newses;
		}

		public News[] ListByCategoryId(SearchNewsCondition condition, int categoryID, int pageSize, int pageNo, out int totalCount, bool isIncludeContent,int? isPublished)
		{
			var newses = db.ListByCategoryId(condition, categoryID, pageSize, pageNo, out totalCount,isPublished);
			foreach (var news in newses)
			{
				news.SourceFrom = BizSourceFrom.Get(news.SourceFromID);
				//news.NewsCategory = BizNewsCategory.Get(news.CategoryID);
				if (isIncludeContent)
				{
					news.NewsContent.AddRange(BizNewsContent.ListNewsContentByNewsID(news.NewsID));
				}
			}
			return newses;
		}

		public News[] ListByCategoryId(int categoryID,EnumOrder order, int pageSize, int pageNo, out int totalCount)
		{
			return db.ListByCategoryId(categoryID, order, pageSize, pageNo,out totalCount);
		}

		public void UpdateAll(News news,int orderNo)
		{
			BizNewsXTag.DeleteAllByNewsId(news.NewsID);
			BizNewsXTag.SaveTags(news.Tags, news.NewsID);
			NewsContent nc = BizNewsContent.Get(news.NewsID, orderNo);
			if (nc != null)
				BizNewsContent.Update(x=>x.NewsID==nc.NewsID&&x.OrderNo==orderNo,x=>new NewsContent { NewsID = news.NewsID,Content=news.Content, OrderNo = orderNo });
			else
				InsertNewsContent(news, orderNo);
				//db.UpdateSelfDefine(news, false, false);
				news.ImagePath = string.IsNullOrEmpty(news.ImagePath) ? Get(news.NewsID).ImagePath : news.ImagePath;
			base.Update(news);
		}

		public void InsertNewsContent(News news, int orderNo)
		{
			BizNewsContent.Insert(new NewsContent { NewsID = news.NewsID, Content = news.Content, OrderNo = orderNo });
		}

		public void Insert(News news,int orderNo)
		{
			base.Insert(news);
			BizNewsXTag.SaveTags(news.Tags, news.NewsID);
			BizNewsContent.Insert(new NewsContent { NewsID = news.NewsID, Content = news.Content, OrderNo=orderNo });
		}

		/// <summary>
		/// 外部模块调用,列出相关新闻
		/// </summary>
		/// <param name="tagIdList"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		public News[] ListReferenceNewsByTags(IList<string> tagIdList, int count, bool isWhenNotEnoughAdd)
		{
			var newses = isWhenNotEnoughAdd ? db.NewsSupplyWhenNotEnough(db.ListReferenceNews(tagIdList,count), count) : db.ListReferenceNews(tagIdList, count);
			return newses;
		}
		/// <summary>
		/// 外部模块调用,列出相关新闻
		/// </summary>
		/// <param name="tags"></param>
		/// <param name="count"></param>
		/// <param name="isWhenNotEnoughAdd"></param>
		/// <returns></returns>
		public News[] ListReferenceNewsByTags(string tags, int count, bool isWhenNotEnoughAdd)
		{
			string[] tagArray = tags.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
			return ListReferenceNewsByTags(tagArray, count, isWhenNotEnoughAdd);
		}

		

		/// <summary>
		/// 列出相关新闻 8 条
		/// </summary>
		/// <param name="newsId"></param>
		/// <param name="count"></param>
		/// <returns></returns>
		public News[] ListReferenceNewsByNewsID(int newsId,bool isWhenNotEnoughAdd)
		{
			IList<string> tagIdList = BizNewsXTag.ListTagNamesByNewsID(newsId);
			News[] newses = isWhenNotEnoughAdd ? db.NewsSupplyWhenNotEnough(db.ListReferenceNewsByNewsID(tagIdList, newsId, 8), 8) : db.ListReferenceNewsByNewsID(tagIdList, newsId, 8);
			return newses;
		}

		public News GetPre(int newsId)
		{
			var news = db.GetBy(n => n.NewsID < newsId);
			return news;
		}

		public News GetNext(int newsId)
		{
			var news = db.GetBy(n => n.NewsID > newsId);
			return news;
		}

		//TODO db层得提供 为0 不更新的函数
		public void IncreaseClickCount(int newsId, int clickCount)
		{
			db.UpdateSelfDefine(new News
			{
				NewsID = newsId,
				ClickCount = ++clickCount
			},false,false);
		}

		public News GetAll(int newsId,int orderNo)
		{
			var news = db.Get(newsId);
			NewsContent nc=BizNewsContent.Get(newsId,orderNo);
			news.Content = nc==null?"":nc.Content;
			news.Tags = BizNewsXTag.GetTagStringsByNewsId(newsId);
			news.NewsContent.AddRange(BizNewsContent.ListNewsContentByNewsID(newsId).OrderBy(x=>x.OrderNo));
			return news;
		}

		/// <summary>
		/// 列出每个新闻分类的头条大眼睛，数量为1个
		/// </summary>
		/// <returns></returns>
		public News[] ListEveryCategoryTopEye()
		{
			return db.ListEveryCategoryTopEye();
		}

		/// <summary>
		/// 列出某一定义列表前x条新闻
		/// </summary>
		/// <param name="number"></param>
		/// <param name="defineType"></param>
		/// <param name="order"></param>
		/// <returns></returns>
		public News[] ListTopXByDefineType(int number, EnumDefineType defineType, EnumOrder order)
		{
			return db.ListTopXByDefineType(number,defineType,order);
		}



		/// <summary>
		/// 列出news分类的大眼睛新闻
		/// </summary>
		/// <param name="number"></param>
		/// <returns></returns>
		public News[] ListCategoryEye(int categoryID)
		{
			return db.ListCategoryTopXByDefineType(5,categoryID, EnumDefineType.分类轮换, EnumOrder.添加时间);
		}

		/// <summary>
		/// 列出分类推荐的news
		/// </summary>
		/// <param name="categoryId"></param>
		/// <returns></returns>
		public News[] ListCategoryRecommendNews(int categoryId)
		{
			return db.ListCategoryTopXByDefineType(5, categoryId, EnumDefineType.我的推荐, EnumOrder.添加时间);
		}

		/// <summary>
		/// 列出推荐新闻,新闻首页5条推荐
		/// </summary>
		/// <returns></returns>
		public News[] ListTop5RecommendNews()
		{
			return ListTopXByDefineType(7, EnumDefineType.我的推荐, EnumOrder.添加时间).OrderByDescending(x=>x.ImagePath).ToArray() ;
		}

		/// <summary>
		/// 列出推荐页面的20
		/// </summary>
		/// <returns></returns>
		public News[] ListTop20RecommendNews()
		{
			return ListTopXByDefineType(20, EnumDefineType.我的推荐, EnumOrder.添加时间).OrderByDescending(x => x.ImagePath).ToArray();
		}

		/// <summary>
		/// 分页列出推荐新闻
		/// </summary>
		/// <returns></returns>
		public News[] ListRemcommendNews( EnumOrder order,int pageSize, int pageNo, out int totalCount)
		{
			return db.ListByDefineType(EnumDefineType.我的推荐, order, pageSize, pageNo, out totalCount);
		}

		/// <summary>
		/// 按照tagName 列出新闻
		/// </summary>
		/// <param name="tagNameList">tag名称列表</param>
		/// <param name="pageSize"></param>
		/// <param name="pageNo"></param>
		/// <param name="totalCount"></param>
		/// <returns></returns>
		public News[] ListNewsByTag(IList<string> tagNameList, int pageSize, int pageNo, out int totalCount)
		{
			return db.ListNewsByTag(tagNameList, pageSize, pageNo, out totalCount);
		}

		/// <summary>
		/// 列出news分类点击靠前的News
		/// </summary>
		/// <returns></returns>
		public IEnumerable<IGrouping<int, News>> ListTopXNewsByCategory()
		{
			News[] news = db.ListTopXNewsByCategory(5);
			IEnumerable<IGrouping<int, News>> groupResult = news.GroupBy<News, int>(x => x.CategoryID);
			return groupResult;
		}

		
		/// <summary>
		/// 列出头条新闻
		/// </summary>
		/// <returns></returns>
		public News[] ListHeadNews()
		{
			return ListTopXByDefineType(3, EnumDefineType.首页轮换, EnumOrder.添加时间);
		}

			/// <summary>
		/// 列出最新5条新闻
		/// </summary>
		/// <param name="number"></param>
		/// <returns></returns>
		public News[] ListTopXLatestNews()
		{
			return db.ListTopXLatestNews(15);
		}

		/// <summary>
		/// 列出某一个分类最新的新闻 数量 8个
		/// </summary>
		/// <param name="categoryId"></param>
		/// <param name="number"></param>
		/// <returns></returns>
		public News[] ListCategoryTopXLatestNews(int categoryId)
		{
			return db.ListCategoryTopXLatestNews(categoryId, 8);
		}

		/// <summary>
		/// 列出top 5 点击次数最多的新闻
		/// </summary>
		/// <param name="number"></param>
		/// <returns></returns>
		public News[] ListTopXHotNews()
		{
			return db.ListTopXHotNews(5);
		}

		/// <summary>
		/// 列出某一分类下面的热门新闻 数量8个
		/// </summary>
		/// <param name="categoryId"></param>
		/// <param name="number"></param>
		/// <returns></returns>
		public News[] ListCategoryTopXHotNews(int categoryId)
		{
			return db.ListCategoryTopXHotNews(categoryId,8);
		}

	}
}
